package com.jxc.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ServletContextAware;

import com.jxc.dao.BaseDaoI;
import com.jxc.dao.CommonDaoI;
import com.jxc.dao.ResourceDaoI;
import com.jxc.dao.RoleResourceDaoI;
import com.jxc.model.po.Resource;
import com.jxc.model.po.RoleResource;
import com.jxc.model.vo.TreeNode;
import com.jxc.model.vo.VResource;
import com.jxc.model.vo.VRole;
import com.jxc.service.ResourceServiceI;

@Service("resourceService")
public class ResourceServiceImpl implements ResourceServiceI,
		ServletContextAware {

	@Autowired
	private BaseDaoI<Resource> resourceDao;
	@Autowired
	private BaseDaoI<RoleResource> roleResourceDao;
	@Autowired
	private ResourceDaoI noSessionResourceDao;
	@Autowired
	private RoleResourceDaoI noSessionRoleResourceDao;
	public static final String SECURITY_CONFIG = "SECURITY_CONFIG";
	public ServletContext servletContext;

	private String str;
	private String usertype;
	
	@Override
	public List<TreeNode> tree(VResource vResource, boolean b) {
		str = vResource.getRoleIds();
		usertype = vResource.getUpusertype().toString();
		
		List<Object> param = new ArrayList<Object>();
		String hql = "from Resource t where t.parent is null ";
		System.out.println(vResource.getId());
		if (vResource != null && vResource.getId() != null) {
			hql = "from Resource t where t.parent.id = ?";
			param.add(vResource.getId());
		}
		List<Resource> l = resourceDao.find(hql, param);
		List<TreeNode> tree = new ArrayList<TreeNode>();
		for (Resource t : l) {
			if(usertype.equals("0")){
				tree.add(this.tree(t, b));
			}else{
				tree.add(this.addForOtherUser(t, b));
			}			
		}
		return tree;
	}

	private TreeNode tree(Resource t, boolean recursive) {
		TreeNode node = new TreeNode();
		node.setId(String.valueOf(t.getId()));
		node.setText(t.getName());
		Map<String, Object> attributes = new HashMap<String, Object>();
		node.setAttributes(attributes);
		if (t.getResources() != null && t.getResources().size() > 0) {
			node.setState("closed");
			if (recursive) {// 递归查询子节点
				List<Resource> l = new ArrayList<Resource>(t.getResources());
				List<TreeNode> children = new ArrayList<TreeNode>();
				for (Resource r : l) {
					TreeNode tn = tree(r, true);
					children.add(tn);
				}
				node.setChildren(children);
				node.setState("open");
			}
		}
		return node;
	}

	//非管理员新增或修改角色管理模块的权限为该用户的权限子集	
	private TreeNode addForOtherUser(Resource t, boolean recursive) {
		List<Object> values = new ArrayList<Object>();
		List<String> list = new ArrayList<String>();
		String hql = "from RoleResource rr where rr.role.id = '"+str+"' order by rr.resource.id ";		
		List<RoleResource> rrList = roleResourceDao.find(hql, values);
		if(rrList!=null&&rrList.size()>0){
			for(RoleResource rr:rrList){				
				list.add(Long.toString(rr.getResource().getId()));
			}
		}
		
		TreeNode node = new TreeNode();
		node.setId(String.valueOf(t.getId()));
		node.setText(t.getName());
		Map<String, Object> attributes = new HashMap<String, Object>();
		node.setAttributes(attributes);
		if (t.getResources() != null && t.getResources().size() > 0) {
			node.setState("closed");
			if (recursive) {// 递归查询子节点
				List<Resource> l = new ArrayList<Resource>(t.getResources());
				List<TreeNode> children = new ArrayList<TreeNode>();
				for (Resource r : l) {
					for(String strtemp:list){
						//代理商和经销商的下级用户都没有角色管理的权限，所以新增和修改都没有角色管理的权限
						if(Long.toString(r.getId()).equals("29") ||  Long.toString(r.getId()).equals("115") ||
								Long.toString(r.getId()).equals("116") || Long.toString(r.getId()).equals("117") ||
								Long.toString(r.getId()).equals("118")){
							break;
						}
						if(Long.toString(r.getId()).equals(strtemp)){
							TreeNode tn = addForOtherUser(r, true);
							children.add(tn);
							break;							
					    }
					}					
				}
				node.setChildren(children);
				node.setState("open");
			}
		}
		return node;
	}
	
	@Override
	public List<VResource> treegrid(VResource vResource) {
		List<Resource> l;
		if (vResource != null && vResource.getId() != null) {
			l = resourceDao.find("from Resource t where t.parent.id = ?",
					new Object[] { vResource.getId() });
		} else {
			l = resourceDao
					.find("from ReResourcesource t where t.parent is null");
		}
		return changeModel(l);
	}

	private List<VResource> changeModel(List<Resource> resources) {
		List<VResource> l = new ArrayList<VResource>();
		if (resources != null && resources.size() > 0) {
			for (Resource t : resources) {
				VResource a = new VResource();
				BeanUtils.copyProperties(t, a);
				if (t.getParent() != null) {
					a.setPid(t.getParent().getId());
					a.setPname(t.getParent().getName());
				}
				if (countChildren(t.getId()) > 0) {
					a.setState("closed");
				}
				l.add(a);
			}
		}
		return l;
	}

	private Long countChildren(Long pid) {
		return resourceDao.count(
				"select count(*) from Resource t where t.parent.id = ?",
				new Object[] { pid });
	}

	@Override
	public List<VResource> loadAll() {
		return noSessionResourceDao.list();
	}

	@Override
	public Map<String, List<VRole>> loadAll(boolean cache) {
		if (servletContext.getAttribute(SECURITY_CONFIG) == null || !cache) {
			List<VResource> list = loadAll();
			HashMap<String, List<VRole>> root = new HashMap<String, List<VRole>>();
			if (list != null && list.size() > 0) {
				for (VResource vResource : list) {
					root.put(vResource.getSign(), noSessionRoleResourceDao
							.getRoleByResource(vResource.getId()));
				}

			}
			servletContext.setAttribute(SECURITY_CONFIG, root);
			return root;
		} else {
			return (Map<String, List<VRole>>) servletContext
					.getAttribute(SECURITY_CONFIG);
		}
	}

	@Override
	public void refresh(List<VResource> data) {
		loadAll(false);
	}

	@Override
	public void removeandrefresh() {
		servletContext.removeAttribute(SECURITY_CONFIG);
		loadAll(false);
	}
	
	@Override
	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
		loadAll(false);
	}

	@Override
	public List<VResource> getSubResources(VResource vResource) {
		List<Resource> list = new ArrayList<Resource>();
		String hql = "from RoleResource t where t.role.id = ? and t.resource.parent.sign=?";
		List<Object> values = new ArrayList<Object>();
		values.add(vResource.getRid());
		values.add(vResource.getSign());
		List<RoleResource> rrList = roleResourceDao.find(hql, values);
		if(rrList!=null&&rrList.size()>0){
			for(RoleResource rr:rrList){
				list.add(rr.getResource());
			}
		}
		return changeModel(list);
	}

	

}
